package com.ruoyi.system.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.asms.controller.AsmsOwnMaintenanceDeptController;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.SysGeographical;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.statistics.vo.NewHistogramVo;
import com.ruoyi.common.core.utils.SecurityUtils;

import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.asms.service.IAsmsAssetFullInfoService;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Service
public class SysDataStatisticsServiceImpl implements ISysDataStatisticsService {

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysUserService userService;
    @Autowired
    private IAsmsAssetFullInfoService assetFullInfoService;

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private ReUsingService reUsingService;
    @Autowired
    private ISysGeographicalService sysGeographicalService;

//    @Autowired
//    private RemoteDeptService remoteDeptService;
//    @Autowired
//    private RemoteAsmsService remoteAsmsService;
    @Autowired
    private SysDeptController deptController;
//    @Autowired
//    private RemoteAsmsService remoteAsmsService;
    @Autowired
    private AsmsOwnMaintenanceDeptController ownMaintenanceDeptController;

    @Override
    public List<DeptJoinVo> deptJoin(String role) {
        List<DeptJoinVo> deptJoinVos = new ArrayList<>();
        R<HashSet<Long>> remoteDept = new R<>();
        if (role != null && role.equals("company"))
            //若是公司查看，则获取维护的学校
            remoteDept = ownMaintenanceDeptController.getODeptIdsByMDeptId(SecurityUtils.getDeptId());

        if (remoteDept.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException("系统异常：远程调用出错！");

        HashSet<Long> ownDeptIds = remoteDept.getData();
        if (ownDeptIds.size() == 0)
            return deptJoinVos;

        CompletableFuture<List<SysDept>> future1 = CompletableFuture.supplyAsync(() ->
                deptService.list(new QueryWrapper<SysDept>()
                        .select(SysDept.DEPT_FULL_NAME, SysDept.CREATE_TIME, SysDept.DEPT_ID)
                        .in(SysDept.DEPT_ID, ownDeptIds).orderByDesc(SysDept.CREATE_TIME).last("limit 10"))
        );

        //查询用户用于计算使用用户的数量
        CompletableFuture<List<SysUser>> future2 = CompletableFuture.supplyAsync(() ->
                userService.list(new QueryWrapper<SysUser>().select(SysUser.DEPT_ID).in(SysUser.DEPT_ID, ownDeptIds))
        );

        //查询资产用于计算学校的资产数量
        CompletableFuture<List<AsmsAssetFullInfo>> future3 = CompletableFuture.supplyAsync(() ->
                assetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .select(AsmsAssetFullInfo.OWN_DEPT_ID).in(AsmsAssetFullInfo.OWN_DEPT_ID, ownDeptIds))
        );

        List<SysDept> sysDepts = new ArrayList<>();
        List<SysUser> users = new ArrayList<>();
        List<AsmsAssetFullInfo> fullInfos = new ArrayList<>();
        try {
            sysDepts = future1.get();
            users = future2.get();
            fullInfos = future3.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        SimpleDateFormat fmt = new SimpleDateFormat("yyyy.MM.dd");

        for (SysDept sysDept : sysDepts) {
            DeptJoinVo deptJoinVo = new DeptJoinVo();

            deptJoinVo.setDeptName(sysDept.getDeptFullName());

            if (sysDept.getCreateTime() != null)
                deptJoinVo.setJoinDate(fmt.format(new Date(sysDept.getCreateTime())));

            int deptAssetNum = 0;
            for (AsmsAssetFullInfo fullInfo : fullInfos) {
                if (fullInfo.getOwnDeptId().equals(sysDept.getDeptId()))
                    deptAssetNum++;
            }
            deptJoinVo.setAssetNum(deptAssetNum);

            int deptUserNum = 0;
            for (SysUser user : users) {
                if (user.getDeptId().equals(sysDept.getDeptId()))
                    deptUserNum++;
            }
            deptJoinVo.setUserNum(deptUserNum);

            deptJoinVos.add(deptJoinVo);
        }
        return deptJoinVos;
    }

    @Override
    public List<DeptJoinWithTypeVo> deptJoinWithType(String role) {
        List<DeptJoinWithTypeVo> deptJoinWithTypeVos = new ArrayList<>();
        R<HashSet<Long>> remoteDept = new R<>();
        if (role != null && role.equals("company"))
            //若是公司查看，则获取维护的学校
            remoteDept = ownMaintenanceDeptController.getODeptIdsByMDeptId(SecurityUtils.getDeptId());

        if (remoteDept.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException("系统异常：远程调用出错！");

        HashSet<Long> ownDeptIds = remoteDept.getData();

        if (ownDeptIds.size() == 0)
            return deptJoinWithTypeVos;

        List<SysDept> depts = deptService.list(new QueryWrapper<SysDept>()
                .select(SysDept.SCHOOL_TYPE, SysDept.DEPT_ID).in(SysDept.DEPT_ID, ownDeptIds));

        String[] deptType = {"幼儿园", "小学", "初中", "高中", "大学"};

        for (int i = 0; i < deptType.length; i ++) {
            DeptJoinWithTypeVo deptJoinWithTypeVo = new DeptJoinWithTypeVo();
            deptJoinWithTypeVo.setDeptType(deptType[i]);
            int schoolNum = 0;
            for (SysDept dept : depts) {
                if (dept.getSchoolType() != null
                        && dept.getSchoolType().equals(i))
                    schoolNum ++;
            }
            deptJoinWithTypeVo.setDeptNum(schoolNum);
            deptJoinWithTypeVos.add(deptJoinWithTypeVo);
        }
        return deptJoinWithTypeVos;
    }

    @Override
    public Integer deptJoinNum(String role) {
        R<HashSet<Long>> remoteDept = new R<>();
        if (role != null && role.equals("company"))
            //若是公司查看，则获取维护的学校
            remoteDept = ownMaintenanceDeptController.getODeptIdsByMDeptId(SecurityUtils.getDeptId());

        if (remoteDept.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException("系统异常：远程调用出错！");

        return remoteDept.getData().size();
    }

    @Override
    public List<NewHistogramVo> thisMonthDeptSign(String role) {
        return null;
    }

    @Override
    public List<ThisMonthDeptUserChangeVo> thisMonthDeptUserChange() {
        //获取当前维护公司维护的学校
        List<ThisMonthDeptUserChangeVo> result = new ArrayList<>();
        R<HashSet<Long>> deptIdR =ownMaintenanceDeptController.getODeptIdsByMDeptId(SecurityUtils.getDeptId());
        if (deptIdR.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException("系统异常：远程调用出错！");
        HashSet<Long> ownDeptIds = deptIdR.getData();
        if (ownDeptIds.size() == 0)
            return result;

        //获取学校的详细信息
        R<List<SysDept>> deptListByIds = deptController.getDeptListByIds(ownDeptIds);
        if (deptListByIds.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException("系统异常：远程调用出错！");
        List<SysDept> schools = deptListByIds.getData();
        HashMap<Long, String> deptIdNameMap = new HashMap<>();
        schools.forEach(item -> deptIdNameMap.put(item.getDeptId(), item.getDeptFullName()));

        StringBuilder deptIdsStr = new StringBuilder();
        int flag = 0;
        for (Long ownDeptId : ownDeptIds) {
            flag ++;
            deptIdsStr.append(ownDeptId.toString());
            if (flag != ownDeptIds.size())
                deptIdsStr.append(",");
        }
        List<ThisMonthDeptUserChangeSQLVo> changeSQLVos = userMapper
                .thisMonthDeptUserChange(reUsingService.getThisMonthStartTime(), System.currentTimeMillis(), deptIdsStr.toString());
        for (ThisMonthDeptUserChangeSQLVo changeSQLVo : changeSQLVos) {
            ThisMonthDeptUserChangeVo changeVo = new ThisMonthDeptUserChangeVo();
            changeVo.setDept(deptIdNameMap.get(changeSQLVo.getDeptId()));
            changeVo.setDate(changeSQLVo.getDate());
            changeVo.setNum(changeSQLVo.getCount());
            result.add(changeVo);
        }
        return result;
    }

    @Override
    public List<BusinessAreaVo> businessArea() {
        List<BusinessAreaVo> result = new ArrayList<>();
        //先获取维护的学校
        R<HashSet<Long>> hashSetR = ownMaintenanceDeptController.getODeptIdsByMDeptId(SecurityUtils.getDeptId());
        if (hashSetR.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException("系统异常：远程调用出错！");
        HashSet<Long> ownDeptIds = hashSetR.getData();
        if (ownDeptIds.size() == 0)
            return result;

        //获取学校详情
        List<SysDept> deptList = deptService.list(new QueryWrapper<SysDept>()
                .select(SysDept.DEPT_ID, SysDept.DEPT_FULL_NAME, SysDept.GEOGRAPHICAL_ID)
                .in(SysDept.DEPT_ID, ownDeptIds));

        //获取学校的资产
        List<AsmsAssetFullInfo> assets = assetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .select(AsmsAssetFullInfo.OWN_DEPT_ID)
                .in(AsmsAssetFullInfo.OWN_DEPT_ID, ownDeptIds));

        //获取区域
        HashSet<Long> geoIds = new HashSet<>();
        deptList.forEach(item -> {
            if (item.getGeographicalId() != null)
                geoIds.add(item.getGeographicalId());
        });

        List<SysGeographical> geographicals = sysGeographicalService.list(new QueryWrapper<SysGeographical>()
                .select(SysGeographical.GEOGRAPHICAL_ID, SysGeographical.LNG, SysGeographical.LAT)
                .in(geoIds.size() > 0, SysGeographical.GEOGRAPHICAL_ID, geoIds));

        HashMap<Long, SysGeographical> geographicalHashMap = new HashMap<>();
        geographicals.forEach(item -> geographicalHashMap.put(item.getGeographicalId(), item));

        for (SysDept dept : deptList) {
            BusinessAreaVo businessAreaVo = new BusinessAreaVo();
            businessAreaVo.setName(dept.getDeptFullName());
            Double[] value = new Double[3];
            SysGeographical sysGeographical = geographicalHashMap.get(dept.getGeographicalId());
            if (sysGeographical != null) {
                value[0] = sysGeographical.getLng();
                value[1] = sysGeographical.getLat();
            }
            int assetNum = 0;
            for (AsmsAssetFullInfo asset : assets) {
                if (dept.getDeptId().equals(asset.getOwnDeptId()))
                    assetNum ++;
            }
            value[2] = (double) assetNum;
            businessAreaVo.setValue(value);
            result.add(businessAreaVo);
        }
        return result;
    }
}
